home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1990,91 by Sozobon, Limited. Authors: Johann Ruegg, Don Dugger
- *
- * Permission is granted to anyone to use this software for any purpose
- * on any computer system, and to redistribute it freely, with the
- * following restrictions:
- * 1) No charge may be made other than reasonable charges for reproduction.
- * 2) Modified versions must be clearly marked as such.
- * 3) The authors are not responsible for any harmful consequences
- * of using this software, even if they result from defects in it.
- *
- * adb.c
- */
-
- #include <setjmp.h>
- #include "adb.h"
-
- #define IN_ADB
- #include "lang.h"
-
- #define CNTLC 3
- #define CNTLS 0x13
- #define CNTLW 0x17
-
- struct file binary;
-
- long dot;
- int dotoff;
- long olddot;
-
- #define DOT (dot+dotoff)
-
- int dotset;
- long maxoff = 256;
- int ibase = 16;
-
- int lastc = 0;
- char sign = 0;
-
- unsigned long regbuf[19];
-
- struct regs regs[] = {
- "pc", ®buf[16],
- "sr", ®buf[17],
- "xsp", ®buf[18],
- "d0", ®buf[0],
- "d1", ®buf[1],
- "d2", ®buf[2],
- "d3", ®buf[3],
- "d4", ®buf[4],
- "d5", ®buf[5],
- "d6", ®buf[6],
- "d7", ®buf[7],
- "a0", ®buf[8],
- "a1", ®buf[9],
- "a2", ®buf[10],
- "a3", ®buf[11],
- "a4", ®buf[12],
- "a5", ®buf[13],
- "a6", ®buf[14],
- "sp", ®buf[15],
- "", 0,
- };
-
- #define NREGS 19
-
- jmp_buf jmpb, trp_buf;
-
- _main()
- {
- extern int _argc;
- extern char **_argv;
-
- main(_argc, _argv);
- exit(0);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *cp;
- extern long ossp;
-
- winopen();
- binary.symptr = 0;
- binary.flags = 0;
- if (argc != 2) {
- prtf("Usage: adb binary\n");
- seeerr();
- exit(1);
- }
- binary.name = argv[1];
-
- if ((binary.fid = open(binary.name, 0)) < 0) {
- /* prtf("%s:cannot open\n", binary.name); */
- prtf(M1, binary.name);
- seeerr();
- exit(2);
- }
- if (setobj(&binary) != 0) {
- /* prtf("%s:bad format\n", binary.name); */
- prtf(M2, binary.name);
- seeerr();
- exit(3);
- }
- if (loadpcs() != 0) {
- /* prtf("%s:bad pexec\n", binary.name); */
- prtf(M3, binary.name);
- seeerr();
- exit(4);
- }
- close(binary.fid);
- relsym();
- vects();
- /* prt("Szadb version 2.0 (english)\n"); */
- prt(M4);
- if (setjmp(trp_buf)) {
- seeerr();
- exit(0);
- }
- adb();
- }
-
- exit(n)
- {
- oldvects();
- winclose();
- _exit(n);
- }
-
- seeerr()
- {
- /* prt("(hit any key)"); */
- prt(M5);
- gemdos(7);
- }
-
- setobj(fp)
- struct file *fp;
- {
- struct fheader hdr;
-
- if (read(fp->fid, &hdr, sizeof(hdr)) != sizeof(hdr))
- return -1;
- if (hdr.magic != MAGIC)
- return -1;
- if (hdr.ssize) {
- lseek(fp->fid, hdr.tsize + hdr.dsize, 1);
- return setsym(fp, (int)(hdr.ssize/sizeof(struct filsym)));
- }
- return 0;
- }
-
- adb()
- {
- int cmddol(), cmdcol(), cmdprt(), cmdwrt(), cmdsreg(), null();
- long getn(), getdot();
- long expr();
- int intr();
- register int c, lc, count;
- int (*f)();
- long (*g)();
- char fmt[128];
-
- f = cmdprt;
- g = getdot;
- lc = '=';
- dot = 0;
- dotoff = 0;
- setjmp(jmpb);
-
- for (;;) {
- prt("> ");
- dotoff = 0;
- c = peekc();
- if (type(c) & (ALPHANUM | SPECX)) {
- dot = expr();
- olddot = dot;
- dotset = 1;
- } else
- dotset = 0;
- if (peekc() == ',') {
- nb();
- count = expr();
- } else
- count = 1;
-
- switch (c = nb()) {
- case '>':
- f = cmdsreg;
- break;
- case '$':
- c = nb();
- f = cmddol;
- break;
- case ':':
- c = nb();
- f = cmdcol;
- break;
- case '?':
- case '/':
- g = getn;
- switch (peekc()) {
-
- case 'w':
- case 'W':
- f = cmdwrt;
- break;
- default:
- f = cmdprt;
- getfmt(fmt);
- case '\n':
- f = cmdprt;
- break;
-
- }
- break;
- case '=':
- f = cmdprt;
- g = getdot;
- if (peekc() != '\n')
- getfmt(fmt);
- break;
- case '\r':
- case '\n':
- c = lc;
- break;
- default:
- f = null;
- count = 1;
- break;
- }
-
- dotoff = 0;
- if (f == cmdprt && g != getdot) {
- prtad(DOT);
- putchr(':');
- putchr('\n');
- }
- while (count--) {
- (*f)(c, fmt, g);
- if (chkbrk())
- break;
- }
- if (f == cmdprt && g != getdot)
- dot += dotoff;
- lc = c;
- while (getchr() != '\n')
- ;
- }
- }
-
- #define LINESZ 80
- static char lbuf[LINESZ+1];
- static int lb_cur, lb_fill;
-
- getchr()
- {
- char c;
-
- if (lastc) {
- c = lastc;
- lastc = 0;
- return c;
- }
-
- if (lb_cur >= lb_fill)
- getline();
- c = lbuf[lb_cur++];
- return c;
- }
-
- getline()
- {
- char c;
-
- lb_fill = lb_cur = 0;
- while (lb_fill < LINESZ) {
- c = getachr();
- if (c == '\b') {
- if (lb_fill) {
- putchr(c);
- lb_fill--;
- }
- } else
- lbuf[lb_fill++] = c;
- if (c == '\n')
- return;
- }
- lbuf[lb_fill++] = '\n';
- return;
- }
-
- getachr()
- {
- long gemdos(), l;
- register int c;
-
- again:
- l = gemdos(7);
-
- if (l == 0x620000L) {
- help();
- goto again;
- }
-
- c = l & 0xff;
- if (c == CNTLW) {
- winswtch();
- c = gemdos(7);
- winswtch();
- goto again;
- } else if (c == CNTLC || c == CNTLS)
- goto again;
-
- if (c == '\r')
- c = '\n';
- if (c != '\b') /* getline will echo \b if not at sol */
- putchr(c);
-
- return(c);
- }
-
- chkbrk()
- {
- char c;
-
- if (gemdos(11) == 0) /* any chars pending ? */
- return 0;
- c = gemdos(7) & 0xff;
- if (c == CNTLC)
- return 1;
- else if (c == CNTLS) {
- c = gemdos(7) & 0xff;
- if (c == CNTLC)
- return 1;
- }
- return 0;
- }
-
- pushc(c)
- int c;
- {
-
- lastc = c;
- return(c);
- }
-
- peekc()
- {
-
- return(pushc(nb()));
- }
-
- nb()
- {
- register int c;
-
- while ((c = getchr()) == ' ' || c == '\t')
- ;
- if (c == '\n')
- pushc(c);
- return(c);
- }
-
- type(c)
- char c;
- {
-
- if (c >= '0' && c <= '9')
- return(NUMERIC);
- if (c >= 'a' && c <= 'f')
- return(HEX);
- if (c >= 'A' && c <= 'F')
- return(HEX);
- if (c >= 'g' && c <= 'z')
- return(ALPHA);
- if (c >= 'G' && c <= 'Z')
- return(ALPHA);
- if (c == '_')
- return(ALPHA);
- switch (c) {
- case '$':
- case ':':
- case '?':
- case '/':
- case '=':
- case ',':
- case '>':
- case '\r':
- case '\n':
- return (SPECCMD);
- }
- return(SPECX);
- }
-
- long
- expr()
- {
- long term();
- long r;
- int c;
-
- r = term();
- for (;;)
- switch (c = nb()) {
- case '+':
- r += term();
- break;
- case '-':
- r -= term();
- break;
- case '*':
- r *= term();
- break;
- case '%':
- r /= term();
- break;
- case '&':
- r &= term();
- break;
- case '|':
- r |= term();
- break;
- case ')':
- default:
- pushc(c);
- return(r);
- }
- }
-
- long
- term()
- {
- long n, getn();
- register int c, base;
- char *cp, buf[NAMEMAX+1];
- struct symbol *sp, *findnam();
- struct regs *rp, *findreg();
-
- if ((c = nb()) == '(') {
- n = expr();
- if (nb() != ')')
- error(UNBAL);
- return(n);
- } else if (c == '\'') {
- n = 0;
- while ((c = getchr()) != '\'')
- if (c == '\n') {
- pushc(c);
- break;
- } else
- n = (n << 8) | c;
- return(n);
- } else if (c == '-') {
- n = term();
- return -n;
- } else if (c == '~') {
- n = term();
- return ~n;
- } else if (c == '<') {
- cp = buf;
- while (type(c = getchr()) & ALPHANUM)
- *cp++ = c;
- *cp = '\0';
- pushc(c);
- if (rp = findreg(buf))
- return *rp->value;
- error(BADRNAME);
- } else if (c == '*') {
- n = term();
- n = getn(n, 4);
- return n;
- } else if (c == '@') {
- n = term();
- n = getn(n, 2);
- return n;
- } else if (c == '.') {
- return dot;
- } else if (c == '&') {
- return olddot;
- } else if (type(c) & ALPHAONLY) {
- cp = buf;
- *cp++ = '_';
- *cp++ = c;
- while (type(c = getchr()) & ALPHANUM)
- *cp++ = c;
- *cp = '\0';
- pushc(c);
- if (sp = findnam(buf + 1, binary.symptr))
- return(sp->value);
- else if (sp = findnam(buf, binary.symptr))
- return(sp->value);
- error(BADNAME);
- }
- n = 0;
- base = ibase;
- if (c == '0') {
- base = 8;
- switch (pushc(getchr())) {
- case 'x':
- base += 6;
- case 't':
- base += 2;
- case 'o':
- getchr();
- c = getchr();
- break;
- default:
- base = ibase;
- break;
- }
- }
- while (type(c) & HEXDIG) {
- if (c >= 'a' && c <= 'f')
- c -= 'a' - '9' - 1;
- if (c >= 'A' && c <= 'F')
- c -= 'A' - '9' - 1;
- n = (n * base) + (c - '0');
- c = getchr();
- }
- pushc(c);
- return(n);
- }
-
- null(c, fmt, get)
- int c;
- char *fmt;
- long (*get)();
- {
- /* prtf("unknown command\n"); */
- prtf(M6);
- return(0);
- }
-
- cmddol(c, fmt, get)
- int c;
- char *fmt;
- long (*get)();
- {
- extern struct regs regs[];
- extern struct bpt bpt[];
- int i;
-
- switch (c) {
- case 'q':
- exit(0);
- case 'd':
- ibase = 10;
- break;
- case 'o':
- ibase = 8;
- break;
- case 'x':
- ibase = 16;
- break;
- case 's':
- maxoff = dot;
- break;
- case 'e':
- prtstbl(binary.symptr);
- break;
- case 'b':
- for (i = 0; i < MAXBPTS; i++)
- if (bpt[i].flag & BP_VALID)
- prbpt(bpt[i].addr);
- break;
- case 'r':
- prregs();
- prbpt(*(regs[PC].value));
- break;
- case 'p':
- prbasepg();
- break;
- case 'c':
- case 'C':
- prstack(c == 'C');
- break;
- default:
- error(UNKNOWN);
- break;
- }
- return(0);
- }
-
- prregs()
- {
- struct regs *rp;
-
- prtreg(®s[PC]);
- prtreg(®s[XSP]);
- prt_sr();
- optnl();
-
- rp = ®s[D0];
- while (rp < ®s[NREGS])
- prtreg(rp++);
- optnl();
- }
-
- prtreg(rp)
- struct regs *rp;
- {
- int i;
-
- i = strlen(rp->name);
- prt(rp->name);
- prtn(*(rp->value), 15-i);
- prt(" ");
- return;
- }
-
- prtstbl(sp)
- struct symbol *sp;
- {
- while (sp) {
- prt(sp->name);
- prt(": ");
- prtn(sp->value, 0);
- putchr('\n');
- sp = sp->next;
- if (chkbrk())
- return;
- }
- return;
- }
-
- cmdwrt(c, fmt, get)
- char c;
- char *fmt;
- long (*get)();
- {
- long l;
-
- c = nb();
- l = expr();
- putn(l, DOT, c == 'w' ? 2 : 4, 1);
- return;
- }
-
- cmdprt(c, fmt, get)
- int c;
- char *fmt;
- long (*get)();
- {
- register int c1;
- long *ip;
- struct symbol *sp;
- long getdot();
- int rep, incr, oldoff;
-
- incr = 0;
- while (c = *fmt++) {
- if (c >= '0' && c <= '9') {
- rep = c - '0';
- while ((c = *fmt++) >= '0' && c <= '9')
- rep = 10*rep + (c - '0');
- } else
- rep = 1;
-
- if (c == 't')
- tab(rep);
- else if (c == '^')
- dotoff -= rep*incr;
- else
- while (rep--) {
-
- oldoff = dotoff;
-
- switch (c) {
- case 'a':
- case 'p':
- prtad(DOT);
- if (c == 'a')
- putchr(':');
- tab(20);
- break;
- case 'i':
- if (get == getdot)
- error(BADCMD);
- puti();
- putchr('\n');
- break;
- case 'o':
- puto((*get)(DOT, 2) & 0xffff, 9);
- break;
- case 'O':
- puto((*get)(DOT, 4), 19);
- break;
- case 'd':
- putd((*get)(DOT, 2), 9);
- break;
- case 'D':
- putd((*get)(DOT, 4), 19);
- break;
- case 'x':
- putx((*get)(DOT, 2) & 0xffff, 9);
- break;
- case 'X':
- putx((*get)(DOT, 4), 19);
- break;
- case 'b':
- puto((*get)(DOT, 1) & 0xff, 4);
- break;
- case 'c':
- putchr((char)(*get)(DOT, 1));
- break;
- case 'S':
- case 's':
- if (get == getdot)
- error(BADCMD);
- while (c1 = (char)(*get)(DOT, 1)) {
- if ((c1 < ' ' || c1 > 127) && (c == 'S'))
- c1 = '.';
- putchr(c1);
- }
- break;
- case '"':
- while ((c = *fmt++) != '"' && c)
- putchr(c);
- if (c != '"')
- fmt--;
- break;
- case 'r':
- putchr(' ');
- break;
- case 'n':
- putchr('\n');
- break;
- case '+':
- dotoff++;
- break;
- case '-':
- dotoff--;
- break;
- default:
- putchr(c);
- break;
- }
-
- incr = dotoff - oldoff;
-
- }
- }
- optnl();
- return;
- }
-
- error(why)
- {
-
- while (getchr() != '\n')
- ;
- prt(errwhy[why]);
- longjmp(jmpb, 1);
- }
-
- prtad(where)
- long where;
- {
- struct symbol *sp, *findsym();
-
- if ((sp = findsym(where, binary.symptr)))
- prtsym(where, sp);
- else
- prtn(where, 0);
- return;
- }
-
- prt_sr()
- {
- long sr;
- int i;
-
- sr = *regs[SR].value;
- prtf("sr %I -> ", sr);
- if (sr & 0x2000)
- prt("Supv");
- else
- prt("User");
-
- prtf(" pri%I ", (sr>>8) & 7);
-
- for (i=4; i>=0; i--)
- if (sr & (1<<i))
- putchr("CVZNX"[i]);
- putchr('\n');
- }
-
- struct regs *
- findreg(s)
- char *s;
- {
- struct regs *rp;
-
- for (rp = regs; rp->value; rp++)
- if (strcmp(s, rp->name) == 0)
- return rp;
- return 0;
- }
-